<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>视频小车遥控页面</title>
    <style type="text/css">
        .container {
            width: 399px;
            height: 500px;
            border: 0px solid rgb(255, 255, 255);
            margin: 0px auto;
            background-color: rgb(88, 88, 188);;
            text-align: center;
        }

        /* 设置头部样式 */
        .image-container {
            width: 399px;
            height: 330px;
            border: 0px solid rgb(220, 217, 218);
            background-color: rgb(115, 177, 255);
            text-align: center;
        }
        
        /* 设置中部样式 */
        .center-container {
            width: 399px;
            height: 30px;
            border: 0px solid rgb(220, 217, 218);
            background-color: rgb(99, 99, 99);
            text-align: center;
        }

        /* 设置主体内容样式 */
        .content {
            width: 399px;
            height: 210px;
            background-color: rgb(48, 45, 45);
        }

        /* 设置主体内容左列的样式 */
        .content .content-left {
            width: 139px;
            height: 100%;
            background-color: rgb(115, 177, 255);
            margin-right: 0px;
            float: left;
        }

        /* 设置主体内容的中间的内容的样式 */
        .content .content-center {
            width: 260px;
            height: 100%;
            background-color: rgb(115, 155, 255);
            float: left;
            margin-left: 0px;
        }

        /* 控件垂直旋转 */
        .slider-vertical {        
            width: 150px;
            height: 20px;
            margin: 0;
            transform-origin: 75px 75px;
            transform: rotate(-90deg);
        }
    </style>
</head>

<body>
    <div class="container">
        <div id="stream-container" class="image-container">
            视频遥控小车V0.1
            <figure>
            <img id="stream" src="" crossorigin>
            </figure>
            https://shop64022682.taobao.com/ DIY模块地址
        </div>
        <div class="center-container">
            <label for="缩放">缩放:</label>
            <input type="range" id="slider" name="slider" min="1" max="5" value="5">
            <span id="sliderValue">5</span>
            <button id="toggle-stream" style="margin-left: 30px;">打开摄像头</button>
        </div>
        <div class="content">
            <div class="content-left">
                    <span id="forwardBackStr">前进</span>
                    <input type="range" id="sliderMoto" class="slider-vertical" name="sliderMoto" min="0" max="10" value="0">
                    <div style="text-align: center">油门: <span id="sliderValueMoto">0</span></div>                    
                    <button id="forwardBackBtn" style="margin-left: 10px;margin-top: 20px;">前进/后退</button>
                    <button id="crawlBtn" style="margin-left: 10px;margin-top: 20px;">蠕行</button>
                    <button id="stopBtn" style="margin-left: 15px;margin-top: 20px;">停车</button>
            </div>
            <div class="content-center">
                <label for="方向">方向:</label> <span id="sliderValueDir">0</span>
                <p></p>
                <button id="dirGoLeft"><-左</button>
                        <input type="range" id="sliderDir" name="sliderDir" min="-16" max="16" step="1" value="0">
                        <button id="dirGoRight">右-></button>
                        <div style="text-align: center;margin-top: 50px;"><button id="dirReturn">回正方向</button></div>
            </div>
            <!-- <div class="content-right">主体内容的右列</div> -->
        </div>
    </div>
</body>

</html>
<script>
    document.addEventListener('DOMContentLoaded', function (event) {
        var baseHost = document.location.origin
        // baseHost = 'http://192.168.0.1'
        var streamUrl = baseHost + ':81'

        const view = document.getElementById('stream')
        const viewContainer = document.getElementById('stream-container')
        const streamButton = document.getElementById('toggle-stream')
        const slider = document.getElementById('slider');
        const sliderValue = document.getElementById('sliderValue');
        const sliderDir = document.getElementById('sliderDir');
        const sliderValueDir = document.getElementById('sliderValueDir');
        const dirReturnButton = document.getElementById('dirReturn');
        const dirGoLeftButton = document.getElementById('dirGoLeft');
        const dirGoRightButton = document.getElementById('dirGoRight');
        const sliderMoto = document.getElementById('sliderMoto');
        const sliderValueMoto = document.getElementById('sliderValueMoto');
        const forwardBackButton = document.getElementById('forwardBackBtn');
        const stopButton = document.getElementById('stopBtn');
        const crawlButton = document.getElementById('crawlBtn');
        const forwardBackStr = document.getElementById('forwardBackStr');        
        var forwardBackFlag = 1; // 1：前进；-1：后退
        


        slider.oninput = function () {
            sliderValue.innerText = this.value;
            const query = `${baseHost}/control?var=framesize&val=${this.value}`
            fetch(query);
            // .then(response => {
            //   console.log(`request to ${query} finished, status: ${response.status}`)
            // })
        }

        const setDir = (dirNum) => {
            // const query = `${baseHost}/control?var=sg90set&val=${((parseInt(dirNum)+16)/12.8+3.75)*100}`
            // 周期20ms
            // 0.5ms 500us  占空比2.5%  -90°
            // 1.0ms 1000us 占空比5.0%  -45°
            // 1.5ms 1500us 占空比7.5%    0°
            // 2.0ms 2000us 占空比10.0%  45°
            // 2.5ms 2500us 占空比12.5%  90°
            // 滑条-16到+16共32份，对应600us到1400us，即每份25us，偏移量为600us
            const query = `${baseHost}/control?var=sg90set&val=${(parseInt(dirNum) + 16) * 25 + 600}`
            fetch(query);
            // .then(response => {
            //   console.log(`request to ${query} finished, status: ${response.status}`)
            // })
        }
        sliderDir.oninput = function () {
            sliderValueDir.innerText = this.value;
            setDir(this.value);
        }
        dirReturnButton.onclick = () => {
            setDir(0);
            sliderValueDir.innerText = 0;
            sliderDir.value = 0;
        }
        dirGoLeftButton.onclick = () => {
            let dirValue = parseInt(sliderValueDir.innerText) - 1;
            if (dirValue < -16) {
                dirValue = -16;
            }
            setDir(dirValue);
            sliderValueDir.innerText = dirValue;
            sliderDir.value = parseInt(dirValue);
        }
        dirGoRightButton.onclick = () => {
            let dirValue = parseInt(sliderValueDir.innerText) + 1;
            if (dirValue > 16) {
                dirValue = 16;
            }
            setDir(dirValue);
            sliderValueDir.innerText = dirValue;
            sliderDir.value = parseInt(dirValue);
        }
        const setSpeed = (speedNum) => {
            sliderValueMoto.innerText = speedNum;
            const speedDeadband = 7; // 电机PWM死区
            if(speedNum!==0){
                speedNum = (10 - speedDeadband) * speedNum / 10 + speedDeadband;
            }
            const query = `${baseHost}/control?var=moto_set&val=${parseFloat(speedNum) * 10 * forwardBackFlag + 100}`
            fetch(query);

        }
        sliderMoto.oninput = function () {
            setSpeed(this.value);
        }
        
        forwardBackButton.onclick = () => {
            setSpeed(0);
            sliderMoto.value = 0;
            forwardBackFlag =  forwardBackFlag*(-1);
            if(forwardBackFlag === -1) {
                forwardBackStr.innerText = '后退';
            }else{
                forwardBackStr.innerText = '前进';
            }
        }
        stopButton.onclick = () => {
            setSpeed(0);
            sliderMoto.value = 0;
        }
        crawlButton.onclick = () => {
            // 先用较高的加速度带动电机。防止直接低速行驶电机堵转，无法推动车体前进
            setSpeed(5);
            sliderMoto.value = 5;
            // 100毫秒后再低速行驶
            setTimeout(() => {
                setSpeed(2);
                sliderMoto.value = 2;                
            }, 100);
        }
        const stopStream = () => {
            window.stop();
            streamButton.innerHTML = '打开摄像头'
        }
        const show = el => {
            el.classList.remove('hidden')
        }
        const startStream = () => {
            const query = `${baseHost}/control?var=framesize&val=5`
            fetch(query)
                .then(response => {
                    console.log(`request to ${query} finished, status: ${response.status}`)
                })
            view.src = `${streamUrl}/stream`
            show(viewContainer)
            slider.value =5,
            sliderValue.innerText = 5
            streamButton.innerHTML = '关闭摄像头'
        }
        // 启动页面时，默认拉取视频
        startStream();
        streamButton.onclick = () => {
            const streamEnabled = streamButton.innerHTML === '关闭摄像头'
            if (streamEnabled) {
                stopStream()
            } else {
                startStream()
            }
        }
    })
</script>